// panic
// 想让二进制文件更小，再设置中把展开调用栈，修改为中止（abort）调用栈
// - 在cargo.toml 中适当的profile部分设置
// - 使用场景： 发生不可恢复的错误时
// - 在定义一个可能失败的函数时，优先考虑返回Result
// - 可以使用panic!
//   - 演示某些概念：unwrap
//   - 原型代码：unwrap、expect
//   - 测试：unwrap、expect

use std::io::{self, Read};
use std::fs::File;

// fn read_text_result() -> Result<String, io::Error> {

//     let mut res = match File::open("hello.txt") {
//         Ok(res) => res,
//         Err(e) => return Err(e),
//     };

//     let mut s: String = String::from("");

//     let mut s: String = String::new();

//     match res.read_to_string(&mut s) {
//         Ok(_) => Ok(s),
//         Err(err) => Err(err),
//     }
// }

// fn read_text_result() -> Result<String, io::Error> {
    
//     // let mut res = match File::open("hello.txt") {
//     //     Ok(res) => res,
//     //     Err(e) => return Err(e),
//     // };
//     //----- 等同于以下代码
//     let mut res =  File::open("hello.txt")?;

//     let mut s: String = String::new();

//     // match res.read_to_string(&mut s) {
//     //     Ok(_) => Ok(s),
//     //     Err(err) => Err(err),
//     // }
//     // -------等同于以下代码
//     res.read_to_string(&mut s)?;
//     Ok(s)
// }
// ------等同于以下代码，可以链式编程
fn read_text_result() -> Result<String, io::Error> {
    let mut s: String = String::new();
    File::open("hello.txt")?.read_to_string(&mut s)?;
    Ok(s)
}


// ? 和 from函数 (use std::convert::From)
// ? 运算符只能用于返回Result的函数
// - std::convert::From  ->用于错误的转化
// - 被?所应用的错误，会被隐式的被from函数处理
// - 接收的错误类型会被转化为当前函数返回类型所定义的错误类型
// - 主要用于  针对不同错误原因，返回同一种错误类型（前提：只要每个错误类型实现了转化为所返回的错误类型的from函数

fn main() {
    // panic!("错误");  // 中止程序
    let f = match File::open("hello.txt") {
        Ok(res) => res,
        Err(err) => {
            panic!("Error")
        }
    };
    println!("Hello, world!");
}
